Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add B_ENEMY_THROW_BALLS, B_PLAYER_THROW_BALLS_SOUND, and B_ENEMY_THROW_BALLS_SOUND #4953

Merged
merged 10 commits into from
Jul 14, 2024
5 changes: 5 additions & 0 deletions include/config/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,4 +268,9 @@
#define B_NEW_IMPACT_PALETTE TRUE // If set to TRUE, it updates the basic 'hit' palette.
#define B_NEW_SURF_PARTICLE_PALETTE TRUE // If set to TRUE, it updates Surf's wave palette.

// Poké Ball animation and sounds
#define B_ENEMY_THROW_BALLS GEN_LATEST // In GEN_6+, enemy Trainers throw Poké Balls into battle instead of them just appearing on the ground and opening.
#define B_ENEMY_THROW_BALLS_SOUND GEN_LATEST // In GEN_5+, enemy Trainer's Poké Balls make a sound when thrown to send out a Pokémon. This can only be used when B_ENEMY_THROW_BALLS is set to GEN_6 or later.
#define B_PLAYER_THROW_BALLS_SOUND GEN_LATEST // In GEN_5+, the player's Poké Balls make a sound when thrown to send out a Pokémon.

#endif // GUARD_CONFIG_BATTLE_H
57 changes: 45 additions & 12 deletions src/pokeball.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@
#include "constants/songs.h"

static void Task_DoPokeballSendOutAnim(u8 taskId);
static void SpriteCB_PlayerMonSendOut_1(struct Sprite *sprite);
static void SpriteCB_PlayerMonSendOut_2(struct Sprite *sprite);
static inline void DoPokeballSendOutSoundEffect(u32 battler);
static inline void *GetOpponentMonSendOutCallback(void);
static inline bool32 IsBattlerPlayer(u32 battler);
static void SpriteCB_MonSendOut_1(struct Sprite *sprite);
static void SpriteCB_MonSendOut_2(struct Sprite *sprite);
static void SpriteCB_OpponentMonSendOut(struct Sprite *sprite);
static void SpriteCB_BallThrow(struct Sprite *sprite);
static void SpriteCB_BallThrow_ReachMon(struct Sprite *sprite);
Expand Down Expand Up @@ -548,6 +551,8 @@ static void Task_DoPokeballSendOutAnim(u8 taskId)
{
u32 throwCaseId, ballId, battlerId, ballSpriteId;
bool32 notSendOut = FALSE;
u32 throwXoffset = (B_ENEMY_THROW_BALLS >= GEN_6) ? 24 : 0;
s32 throwYoffset = (B_ENEMY_THROW_BALLS >= GEN_6) ? -16 : 24;

if (gTasks[taskId].tFrames == 0)
{
Expand Down Expand Up @@ -575,14 +580,16 @@ static void Task_DoPokeballSendOutAnim(u8 taskId)
gBattlerTarget = battlerId;
gSprites[ballSpriteId].x = 24;
gSprites[ballSpriteId].y = 68;
gSprites[ballSpriteId].callback = SpriteCB_PlayerMonSendOut_1;
gSprites[ballSpriteId].callback = SpriteCB_MonSendOut_1;
DoPokeballSendOutSoundEffect(battlerId);
break;
case POKEBALL_OPPONENT_SENDOUT:
gSprites[ballSpriteId].x = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X);
gSprites[ballSpriteId].y = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y) + 24;
gSprites[ballSpriteId].x = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X) + throwXoffset;
gSprites[ballSpriteId].y = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y) + throwYoffset;
gBattlerTarget = battlerId;
gSprites[ballSpriteId].data[0] = 0;
gSprites[ballSpriteId].callback = SpriteCB_OpponentMonSendOut;
gSprites[ballSpriteId].callback = GetOpponentMonSendOutCallback();
DoPokeballSendOutSoundEffect(battlerId);
break;
default:
gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
Expand All @@ -609,6 +616,22 @@ static void Task_DoPokeballSendOutAnim(u8 taskId)
PlaySE(SE_BALL_THROW);
}

static inline void DoPokeballSendOutSoundEffect(u32 battler)
{
if (IsBattlerPlayer(battler) && B_PLAYER_THROW_BALLS_SOUND < GEN_5)
return;

if (!IsBattlerPlayer(battler) && B_ENEMY_THROW_BALLS_SOUND < GEN_5)
return;

PlaySE(SE_BALL_THROW);
}

static inline void *GetOpponentMonSendOutCallback(void)
{
return (B_ENEMY_THROW_BALLS >= GEN_6) ? SpriteCB_MonSendOut_1 : SpriteCB_OpponentMonSendOut;
}

// This sequence of functions is very similar to those that get run when
// a Pokéball gets thrown at a wild Pokémon, starting at SpriteCB_Ball_Arc.
// These do not seem to get run.
Expand Down Expand Up @@ -1110,23 +1133,33 @@ static void SpriteCB_BallThrow_CaptureMon(struct Sprite *sprite)
}
}

static void SpriteCB_PlayerMonSendOut_1(struct Sprite *sprite)
static inline bool32 IsBattlerPlayer(u32 battler)
{
return (battler % B_POSITION_PLAYER_RIGHT) ? FALSE : TRUE;
}

static void SpriteCB_MonSendOut_1(struct Sprite *sprite)
{
bool32 isPlayer = IsBattlerPlayer(sprite->sBattler);
u32 coordX = (isPlayer) ? BATTLER_COORD_X_2 : BATTLER_COORD_X;
u32 coordY = (isPlayer) ? BATTLER_COORD_Y_PIC_OFFSET : BATTLER_COORD_Y;

sprite->data[0] = 25;
sprite->data[2] = GetBattlerSpriteCoord(sprite->sBattler, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(sprite->sBattler, BATTLER_COORD_Y_PIC_OFFSET) + 24;
sprite->data[2] = GetBattlerSpriteCoord(sprite->sBattler, coordX);
sprite->data[4] = GetBattlerSpriteCoord(sprite->sBattler, coordY) + 24;
sprite->data[5] = -30;
sprite->oam.affineParam = sprite->sBattler;
InitAnimArcTranslation(sprite);
sprite->callback = SpriteCB_PlayerMonSendOut_2;
sprite->callback = SpriteCB_MonSendOut_2;
}

#define HIBYTE(x) (((x) >> 8) & 0xFF)

static void SpriteCB_PlayerMonSendOut_2(struct Sprite *sprite)
static void SpriteCB_MonSendOut_2(struct Sprite *sprite)
{
u32 r6;
u32 r7;
bool32 rightPosition = (IsBattlerPlayer(sprite->sBattler)) ? B_POSITION_PLAYER_RIGHT : B_POSITION_OPPONENT_RIGHT;

if (HIBYTE(sprite->data[7]) >= 35 && HIBYTE(sprite->data[7]) < 80)
{
Expand Down Expand Up @@ -1169,7 +1202,7 @@ static void SpriteCB_PlayerMonSendOut_2(struct Sprite *sprite)
sprite->data[0] = 0;

if (IsDoubleBattle() && gBattleSpritesDataPtr->animationData->introAnimActive
&& sprite->sBattler == GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT))
&& sprite->sBattler == GetBattlerAtPosition(rightPosition))
sprite->callback = SpriteCB_ReleaseMon2FromBall;
else
sprite->callback = SpriteCB_ReleaseMonFromBall;
Expand Down
Loading